switch문을 이용해서 해결 프로그램을 동적으로 선택
#include <iostream>
#include <cstdlib>
class matrix{};
class vector{};
void cg(const matrix& A, const vector& b, vector& x);
void bicg(const matrix& A, const vector& b, vector& x);
int main(int argc, char* argv[]){
matrix A;
vector b, x;
int solver_choice=argc>=2?std::atoi(argv[1]):0;
switch(solver_choice){
case 0: cg(A, b, x); break;
case 1: bicg(A, b, x): break;
};
}
위 코드를 사용하면, 런타임에 실행 함수를 선택할 수 있지만, 소스 코드의 복잡도에 따라 확장이 어려울 수 있다.
블록을 함수에 캡슐화하고, 해당 함수를 인수로 호출하면 이를 해결할 수 있다.
struct solver{
virtual void operator()()=0;
virtual ~solver() {}
};
struct cg_solver: solver{
virtual void operator()() override { cg(A, b, x); }
};
struct bicg_solver: solver{
virtual void operator()() override { bicg(A, b, x); }
};
위 애플리케이션을 인터페이스 타입인 solver의 포인터를 정의하고, 해당 포인터를 원하는 해결 프로그램에 할당
unique_ptr<solver> my_solver;
switch(solver_choie){
case 0: my_solver=unique_ptr<cg_solver>(new cg_solver); break;
case 1: my_solver=unique_ptr<bicg_solver>(new bicg_solver); break;
};
위와 같은 패턴을 팩토리(Factory) 패턴이라고 한다.
C++14에서 make_unique를 도입되었다.
unique_ptr<solver> my_solver;
switch(solver_choice){
case 0: my_solver=make_unique<cg_solver>(); break;
case 1: my_solver=make_unique<bicg_sovler(); break;
};
이후 포인터를 이용해서 해당 함수를 호출할 수 있다.
다형성 함수 포인터를 사용하면, 각 선택 항목을 분리하고, 이련의 팩토리와 포인터를 통한 단일 호출로 분해 가능
struct pc{
virtual void operator()()=0;
virtual ~pc(){}
};
struct solver{};
(*my_sovler)(A, b, x);
C++는 가상 템플릿 함수를 금지한다(잠재적으로 무한 가상 테이블을 가질 수 있다.)